// addrspace.h 
//	Data structures to keep track of executing user programs 
//	(address spaces).
//
//	For now, we don't keep any information about address spaces.
//	The user level CPU state is saved and restored in the thread
//	executing the user program (see thread.h).
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved.  See copyright.h for copyright notice and limitation 
// of liability and disclaimer of warranty provisions.

#ifndef ADDRSPACE_H
#define ADDRSPACE_H

#include "copyright.h"
#include "filesys.h"
#include "table.h"
//#include "ipt.h"
#include "noff.h"

#define UserStackSize		1024 	// increase this as necessary!

#define MaxOpenFiles 256
#define MaxChildSpaces 256

/**************************************
changes related to project II
**************************************/
#ifdef CHANGED

#define MAX_NUM_PROCESSES	20
#define MAX_NUM_THREADS		850

struct ThreadTable		//thread table for each process
{
	bool threadStatus;		//active or not
	int topOfStack;			//address to the top of the stack
	int ProcessID;
};

enum PageStatus{mem,exec,sw,idata,udata};
//extends translation entry class

class ExtendedPageTable:public TranslationEntry{
public:
   PageStatus pagestatus; 
   int ProcessID;
   int ExecLoc;		//to calculate offset
};


struct ProcessTable	
{
int topOfStack;
int activeThreads;//number of active threads in a process
int totalThreads;//total number of threads in a process	 									
ThreadTable sthreadTable[MAX_NUM_THREADS];		
bool processStatus;		
};

extern int userProcesses;									
//Counts the number of User Processes
extern int activeThreads;									
//Number of Active User Threads
extern int totalThreads;									
//Total number of threads

extern Lock *PageTableLock[MAX_NUM_PROCESSES];
extern Lock *ProcessTableLock;
extern ProcessTable myProcessTable[MAX_NUM_PROCESSES];

#endif

class AddrSpace {
  public:
    AddrSpace(OpenFile *executable);	// Create an address space,
					// initializing it with the program
					// stored in the file "executable"
    ~AddrSpace();			// De-allocate an address space
    int getID();    			// returns process ID
    void InitRegisters();		// Initialize user-level CPU registers,
					// before jumping to user code

    void SaveState();			// Save/restore address space-specific
    void RestoreState();		// info on a context switch
    Table fileTable;			// Table of openfiles
    NoffHeader noffH;
public:
	void DeallocateProcessTable(int nProcessID);	
	void InitializeProcessThreadTable(int nProcessID);		
	int PopulateProcessTable(int nProcessID);		
	void DeallocatePageTable(int nProcessID, int nThreadID);
	
public:
	void UpdatePageTableOnFORK(int nProcessID);// Update an Entry in the page table entry of Fork (thread)
	int AddressSpaceIndex;		// Space index of the address space
	unsigned int newnumpages; //used in multiprogramming							

public:
    ExtendedPageTable *extpagetable;
    OpenFile *execFile;
    int id;
    TranslationEntry *pageTable;	// Assume linear page table translation
    TranslationEntry *tlb; 					// for now!
    unsigned int numPages, numStackPages,newnumPages, numCodeExecPages;		// Number of total pages in the virtual 
						// address space and number for code  part and init data part
};

//IPT as a part of addrspace
class InvertedPageTable:public TranslationEntry{

public:
//constructor
InvertedPageTable();
//data
//enum PageType{CODE, DATA, MIXED};
//PageType pagetype;
PageStatus pagestatus;
int ProcessID;
bool isEmpty;
AddrSpace *space;

					
};

#endif // ADDRSPACE_H
